#include "stdlib.h"
#include "stdarg.h"
#include "arg.h"
#include "methods.h"

char *argv0;

static char *opt_in = NULL;
static char *opt_out = NULL;
static char *opt_method = NULL;

//extern struct methods t[METHODS];

/* kills program while printing terminating message */
void die(const char *errstr, ...) {
    va_list ap;

    va_start(ap, errstr);
    vfprintf(stderr, errstr, ap);
    va_end(ap);
    exit(1);
}

/* prints usage string before exiting */
void usage(void) {
    die("usage: spngfx [-vl] [-f ifile] [-o ofile] [-m method]\n"
        "       -f:     reads from stdin if not specified\n"
        "       -o:     outputs to stdout if not specified\n"
        "       -l:     list methods\n"
        "       -h:     prints this usage\n"
        "       -v:     print version\n");
}

int main(int argc, char **argv) {
    int seq[METHODS];
    size_t seq_n = 0;

    /* arg parsing */
    ARGBEGIN {
    case 'f':
        opt_in = EARGF(usage());
        break;
    case 'o':
        opt_out = EARGF(usage());
        break;
    case 'm':
        opt_method = EARGF(usage());

        int found = 0;
        for (int i = 0; i < METHODS; i++) {
            if (strcmp(opt_method, "none") == 0)
                continue;
            if (strcmp(opt_method, t[i].name) == 0) {
                if (t[i].f == NULL)
                    break;
                //(*t[i].f)(png);
                seq[seq_n++] = i;
                found = 1;
            }
        }

        if (!found)
            fprintf(stderr, "spngfx: method %s not implemented\n", opt_method);

        break;
    case 'l':
        printf("methods: ");
        for (int i = 0; i < METHODS - 1; i++)
            printf("%s ", t[i].name);
        printf("%s\n", t[METHODS - 1].name);
        return 0;
    case 'h':
        usage();
    case 'v':
        die("spngfx 2nd edition v2.31 (c) 2019-2022 strlst\n");
    } ARGEND;

    if (!seq_n)
        die("spngfx: must specify valid method to apply to image (-h for help)\n");

    if (!opt_in)
        opt_in = "/dev/stdin";

    if (!opt_out)
        //die("spngfx: must specify output file (-h for help)\n");
        opt_out = "/dev/stdout";

    if (!opt_method)
        opt_method = "none";

    spng *png = readpng(opt_in);
    closepng(png);

    if (strcmp(opt_out, "/dev/stdout") != 0)
        printpng_meta(png);
    //printpng_content(png);

    /* exec all seq */
    for (int i = 0; i < seq_n; i++)
        (*t[seq[i]].f)(png);

    writepng(png, opt_out);
    freepng(png);

    return 0;
}
